/**
 * Copyright (c) 2009  Collaborative Development Group, C.S. Dept., University of Bari
 *
 * All rights reserved. This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License v1.0  which accompanies this distribution, and is 
 * available at http://www.eclipse.org/legal/epl-v10.html
 */
package it.uniba.di.cdg.penelope;

import static org.junit.Assert.*;
import it.uniba.di.cdg.penelope.presenterfirst.SUT;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

/**
 * Ensure that {@link AbstractBundleLifecycleAwareAspect}-derived aspects are correctly woven into Activator
 * instances. 
 */
@RunWith( MockitoJUnitRunner.class )
public class BundleLifecycleIntegrationTest {

	@SUT
	@Aspect( "perthis( thisBundleActivator() )" )
	public static class ActivatorLifecycleTestAspect extends AbstractBundleLifecycleAwareAspect {
		private static ActivatorLifecycleTestAspect instance;
		private boolean activated;
		private boolean deactivated;

		/* (non-Javadoc)
		 * @see it.uniba.di.cdg.penelope.AbstractBundleLifecycleAwareAspect#thisBundleActivator()
		 */
		@Pointcut( "this( it.uniba.di.cdg.penelope.BundleLifecycleIntegrationTest$MockActivator )" )
		protected void thisBundleActivator() {}
		
		public ActivatorLifecycleTestAspect() {
			instance = this;
		}

		/* (non-Javadoc)
		 * @see it.uniba.di.cdg.penelope.AbstractBundleLifecycleAwareAspect#onBundleActivated(org.osgi.framework.BundleContext)
		 */
		@Override
		protected void onBundleActivated( BundleContext bc ) {
			this.activated = true;
		}
		
		/* (non-Javadoc)
		 * @see it.uniba.di.cdg.penelope.AbstractBundleLifecycleAwareAspect#onBundleDeactivating(org.osgi.framework.BundleContext)
		 */
		@Override
		protected void onBundleDeactivating( BundleContext bc ) {
			this.deactivated = true;
		}

		/**
		 * @return the instance
		 */
		public static ActivatorLifecycleTestAspect getInstance() {
			return instance;
		}

		/**
		 * @return the activated
		 */
		public boolean isActivated() {
			return activated;
		}

		/**
		 * @return the deactivated
		 */
		public boolean isDeactivated() {
			return deactivated;
		}

		/**
		 * Reset this aspect state. 
		 */
		public void reset() {
			this.activated = false;
			this.deactivated = false;
		}
	}

	public static class MockActivator implements BundleActivator {
		/* (non-Javadoc)
		 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
		 */
		@Override
		public void start( BundleContext context ) throws Exception {
			// Nothing: just provide an hook for the SUT
		}

		/* (non-Javadoc)
		 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
		 */
		@Override
		public void stop( BundleContext context ) throws Exception {
			// Nothing: just provide an hook for the SUT
		}
	}

	private MockActivator activator;

	@Mock
	private BundleContext bc;
	
	@Before
	public void createActivator() {
		this.activator = new MockActivator();
		ActivatorLifecycleTestAspect.getInstance().reset();
	}
	
	@Test
	public void shouldCaptureStart() throws Exception {
		activator.start( bc );
		assertTrue( ActivatorLifecycleTestAspect.getInstance().isActivated() );
	}
	
	@Test
	public void shouldCaptureStop() throws Exception {
		activator.stop( bc );
		assertTrue( ActivatorLifecycleTestAspect.getInstance().isDeactivated() );
	}
}
